/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aiaudio.storage.simple;

import aiaudio.collaborative.CollaborativeAudioTrainingManager;
import aiaudio.collaborative.RandomGenerator;
import aiaudio.storage.api.IArtist;
import aiaudio.storage.api.IUser;
import aiaudio.storage.api.InternalException;
import aiaudio.storage.api.RevereUserArtistTuple;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Nastya
 */
public class StorageFileReader {

    private BufferedReader reader;
    private List<IUser> users = new ArrayList<IUser>();
    private List<IArtist> artists = new ArrayList<IArtist>();
    private HashMap<RevereUserArtistTuple, Double> ratings = new HashMap<RevereUserArtistTuple, Double>();
    private SimpleIncludeAudioTrainingStorage storage;
    private static String DELIMITER = "\t";

    public SimpleIncludeAudioTrainingStorage getStorage() {
        return storage;
    }

    public StorageFileReader(String filename) throws FileNotFoundException, IOException, TooManyItemsException {
        reader = new BufferedReader(new FileReader(filename));
        read(filename);
    }

    private void read(String filename) throws IOException, TooManyItemsException {
        String header = reader.readLine();
        parseArtists(header);
        String line;
        while ((line = reader.readLine()) != null) {
            parseDataLine(line);
        }
        storage = new SimpleIncludeAudioTrainingStorage(filename, users, artists, ratings);
    }

    private void parseArtists(String header) {
        StringTokenizer tokenizer = new StringTokenizer(header, DELIMITER);
        int num = 0;
        while (tokenizer.hasMoreTokens()) {
            String tok = tokenizer.nextToken();
            if (num > 0) {
                artists.add(new Artist(tok, tok));
            }
            num++;
        }
    }

    private void parseDataLine(String line) {
        String currentLine = line;
        int nextDelim = currentLine.indexOf(DELIMITER);
        int num = 0;
        User user = null;
        while (nextDelim != -1) {
            String val = currentLine.substring(0, nextDelim);
            if (num == 0) {
                user = new User(val);
                users.add(user);
            } else {
                double value = parseToDouble(val);
                ratings.put(new RevereUserArtistTuple(artists.get(num - 1), user), value);
            }
            if (nextDelim == 0) {
                currentLine = currentLine.substring(nextDelim + 1);
            } else if (nextDelim == -1) {
                currentLine = "";
                break;
            } else {
                currentLine = currentLine.substring(nextDelim + 1);
            }
            nextDelim = currentLine.indexOf(DELIMITER);
            num++;
        }

    }

    public static void main(String[] args) throws FileNotFoundException, IOException, TooManyItemsException, InternalException {
        StorageFileReader storageFileReader = new StorageFileReader("neuro_matrix_2.txt");
        System.out.println("parsed");
        CollaborativeAudioTrainingManager manager = new CollaborativeAudioTrainingManager(storageFileReader.getStorage(), 1);
//        CollaborativeAudioTrainingManager manager = new CollaborativeAudioTrainingManager(RandomGenerator.generateRandomStorage(100, 30, 7), 1);
        manager.Run();
        System.out.println("trained");
        StatisticsLogger logger = new StatisticsLogger(manager.getResultRatings());
        logger.write("statistics_1.txt");
        
    }

    private double parseToDouble(String val) {
        if (val == null || val.trim().isEmpty()) {
            return 0;
        }
        String result = val.replace(',', '.');
        return Double.parseDouble(result);
    }
}
